﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using HigLabo.Net.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace HigLabo.Net.Twitter
{
    /// <summary>
    /// 
    /// </summary>
    public class Status : ResponseObject 
    {
        /// <summary>
        /// Unused. Future/beta home for status annotations.
        /// </summary>
        public String Annotations { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public List<Int64> Contributors { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public BoundingBox Coordinates { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public DateTimeOffset CreatedAt { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public CurrentUserRetweet CurrentUserRetweet { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Entities Entities { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Int32? FavoriteCount { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Boolean? Favorited { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String FilterLevel { set; get; }
        /// <summary>
        /// Deprecated. Nullable. Use the "coordinates" field instead.
        /// </summary>
        public String Geo { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Int64 ID { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String IDString { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String InReplyToScreenName { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Int64? InReplyToStatusID { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String InReplyToStatusIDString { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Int64? InReplyToUserID { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String InReplyToUserIDString { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String Language { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Place Place { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Boolean? PossiblySensitive { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Scopes Scopes { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Int32 RetweetCount { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Boolean Retweeted { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String Source { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String Text { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Boolean Truncated { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public User User { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Boolean WithheldCopyright { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public List<String> WithheldInCountries { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public String WithheldScope { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public Status RetweetedStatus { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public MetaData MetaData { set; get; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonText"></param>
        public Status(String jsonText)
        {
            if (!String.IsNullOrEmpty(jsonText))
            {
                this.SetProperty(jsonText);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonText"></param>
        public override void SetProperty(string jsonText)
        {
            var d = this.SetData(jsonText);

            this.Annotations = d.ToString("annotations");
            if (!String.IsNullOrEmpty(d.ToString("contributors")))
            {
                this.Contributors = new List<Int64>();
                var cc = JsonConvert.DeserializeObject(d.ToString("contributors")) as JContainer;
                foreach (var i in cc)
                {
                    this.Contributors.Add(Convert.ToInt64(i.ToString()));
                }
            }
            this.Coordinates = new BoundingBox(d.ToString("coordinates"));
            this.CreatedAt = d.CastToDateTimeOffset("created_at") ?? this.CreatedAt;
            this.CurrentUserRetweet = new CurrentUserRetweet(d.ToString("current_user_retweet"));
            this.Entities = new Entities(d.ToString("entities"));
            this.FavoriteCount = d.ToInt32("favorite_count");
            this.Favorited = d.ToBoolean("favorited");
            this.FilterLevel = d.ToString("filter_level");
            this.Geo = d.ToString("geo");
            this.ID = d.ToInt64("id") ?? 0;
            this.IDString = d.ToString("id_str");
            this.InReplyToScreenName = d.ToString("in_reply_to_screen_name");
            this.InReplyToStatusID = d.ToInt64("in_reply_to_status_id");
            this.InReplyToStatusIDString = d.ToString("in_reply_to_status_id_str");
            this.InReplyToUserID = d.ToInt64("in_reply_to_user_id");
            this.InReplyToUserIDString = d.ToString("in_reply_to_user_id_str");
            this.Language = d.ToString("lang");
            this.Place = new Place(d.ToString("place"));
            this.PossiblySensitive = d.ToBoolean("possibly_sensitive");
            this.Scopes = new Scopes(d.ToString("scopes"));
            this.RetweetCount = d.ToInt32("retweet_count") ?? 0;
            this.Retweeted = d.ToBoolean("retweeted") ?? this.Retweeted;
            this.Source = d.ToString("source");
            this.Text = d.ToString("text");
            this.Truncated = d.ToBoolean("truncated") ?? this.Truncated;
            this.User = new User(d.ToString("user"));
            this.WithheldCopyright = d.ToBoolean("withheld_copyright") ?? this.WithheldCopyright;
            //###
            if (!String.IsNullOrEmpty(d.ToString("withheld_in_countries")))
            {
                this.WithheldInCountries = new List<string>();
            }
            this.WithheldScope = d.ToString("withheld_scope");
            this.RetweetedStatus = new Status(d.ToString("retweeted_status"));
            this.MetaData = new MetaData(d.ToString("metadata"));
        }

        public override string ToString()
        {
            return String.Format("{0} {1}", this.CreatedAt.ToString("MM/dd HH:mm:ss"), this.Text);
        }
    }
}
